#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
using namespace std;
int fa[155];

struct point {
    int x, y;
} p[155];
char str[155];
double d[155][155], maxd[155], ad[155];
double dist(double x1, double y1, double x2, double y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void merge(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    fa[y] = x;
}
bool together(int x, int y) { return find(x) == find(y); }
void init(int n) {
  
    for (int i = 1; i <= n; i++) fa[i] = i;
}
int main() {
    int n;
    scanf("%d", &n);
    init(n);
    for (int i = 1; i <= n; i++) scanf("%d%d", &p[i].x, &p[i].y);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++) {
            int c;
            scanf("%1d", &c);
            if (i == j)
                d[i][j] = 0;
            else if (c == 1) {
                d[i][j] = dist(p[i].x, p[i].y, p[j].x, p[j].y);
                merge(i, j);
            }
            else
                d[i][j] = 1 << 30;
        }
    for (int k = 1; k <= n; k++)
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++)
            if (together(i, j)) maxd[i] = max(maxd[i], d[i][j]);
        ad[find(i)] = max(ad[find(i)], maxd[i]);
    }
    double ans = 1 << 30;
    for (int i = 1; i <= n; i++)
        for (int j = i + 1; j <= n; j++)
            if (!together(i, j))
                ans = min(ans,
                    max(maxd[i] + maxd[j] + dist(p[i].x, p[i].y, p[j].x, p[j].y),
                        max(ad[find(i)], ad[find(j)])));
    printf("%.6lf\n", ans);
    return 0;
}